package us.rtsp.android.twitpicshare;
/*
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;

import org.json.JSONObject;
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

import us.rtsp.android.twitpicshare.R;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import us.rtsp.android.twitpicshare.net.ByteArrayBody;

import android.Manifest;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class SendTweet extends Activity {
	
	public static final String TAG = "TwitPicShare";
	public static final String USER_AGENT = "twitpicshare/1.0";
	public static final String IMAGE_FILENAME = "u.jpg";
	public static final String IMAGE_MIME = "image/jpeg";
	
	public static final int MENU_PREFERENCES = 1;
	public static final int MENU_CANCEL = 2;
	
	private static final Integer DEFAULT_POST_REQUEST_TIMEOUT = 20000;
	
	protected SharedPreferences mSP;
	protected ProgressDialog mProgressDialog;
	protected Uri mUri = null;
	
	private TextView lblCharLeft;
	private TextView lblFileAttached;
	private Button btnSend;
	private EditText txtCompose;
	private ImageView imgAttached;
	
	private int mCurrentChars = 0;
	private int mLimitChars = 140;
	private String mUsername;
	private String mPassword;
	private String mPicGateway;
	private boolean mUseSecureGateway;
	private String mSecurePicGateway;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate()");
        setContentView(R.layout.main);
        
        mSP = PreferenceManager.getDefaultSharedPreferences(this);
        getAllPreferences();
        
        lblCharLeft = (TextView) findViewById(R.id.lblCharLeft);
        txtCompose = (EditText) findViewById(R.id.txtCompose);
        btnSend = (Button) findViewById(R.id.btnSend);
        lblFileAttached = (TextView) findViewById(R.id.lblFileAttached);
        imgAttached = (ImageView) findViewById(R.id.imgAttached);

        if (mUsername == null || mUsername.length() == 0 ||
        		mPassword == null || mPassword.length() == 0 ||
        		mPicGateway == null || mPicGateway.length() == 0) {
        	startActivity(new Intent(SendTweet.this, PreferencesActivity.class));
        }
        initUI();
    }
    
    @Override
    public void onStart() {
    	super.onStart();
		final Intent intent = getIntent();
		Log.d(TAG, "onStart() " + intent.getAction());
		if (Intent.ACTION_SEND.equals(intent.getAction())) {
			final Bundle extras = intent.getExtras();
			mUri = (Uri) extras.getParcelable(Intent.EXTRA_STREAM);
			lblFileAttached.setText((CharSequence)mUri.toString());
			lblCharLeft.setText((CharSequence) "0");
			try {
				InputStream imgContext = getContentResolver().openInputStream(mUri);
				imgAttached.setImageBitmap(rescaleBitmap(imgContext));
				imgContext.close();
//			} catch (FileNotFoundException e) {
//				Log.d(TAG, "onStart() FileNotFoundException " + e.getMessage() + " for " + mUri.toString());
			} catch (Exception e) {
				Log.d(TAG, "onStart() Exception " + e.getMessage() + " for " + mUri.toString());
			}
		}
    }
    
    protected void initUI() {
    	btnSend.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				sendMessage();
			}
		});
    	txtCompose.addTextChangedListener(new TextWatcher() {
			public void afterTextChanged(Editable s) {
				mCurrentChars = s.length();
				lblCharLeft.setText(String.valueOf(mLimitChars - mCurrentChars));
			}

			public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
			public void onTextChanged(CharSequence s, int start, int before, int count) {}
		});
    	txtCompose.setOnKeyListener(new View.OnKeyListener() {
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				if (event.getAction() == KeyEvent.ACTION_DOWN) {
					mCurrentChars = txtCompose.length();
					switch (keyCode) {
					case KeyEvent.KEYCODE_DPAD_CENTER:
						sendMessage();
						return true;
					case KeyEvent.KEYCODE_ENTER:
						if (event.isAltPressed()) {
							txtCompose.append("\n");
							return true;
						}
					default:
						if (keyCode != KeyEvent.KEYCODE_DEL && mCurrentChars > mLimitChars) {
							return true;
						}
						lblCharLeft.setText(String.valueOf(mLimitChars - mCurrentChars));
						break;
					}
				}
				return false;
			}
		});
    }
    
    void sendMessage() {
    	String msg = txtCompose.getText().toString();
    	if (TextUtils.isEmpty(msg.trim())) {
			Toast.makeText(SendTweet.this, R.string.empty_message, Toast.LENGTH_SHORT).show();
		} else {
			showDialog(1);
			Thread thread = new Thread(mSendUpdate);
			thread.start();
			closeSoftKeyboard();
		}
    }

	/**
	 * Close the on-screen keyboard.
	 */
	private void closeSoftKeyboard() {
		InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		inputMethodManager.hideSoftInputFromWindow(txtCompose.getWindowToken(), 0);
	}
	
	/**
	 * rescaleBitmap from com.sugree.jibjib.SendTweet
	 * 
	 * @param is
	 * @return scaled image
	 */
	protected Bitmap rescaleBitmap(InputStream is) {
		Log.d(TAG, "rescaleBitmap() start");
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inSampleSize = 2;
		
		Bitmap orig = BitmapFactory.decodeStream(is, null, options);
		int width = orig.getWidth();
		int height = orig.getHeight();
		if (width < 500 && height < 500) {
			return orig;
		}
		Log.d(TAG, "rescaleBitmap() " +  width + "," + height);
		int newWidth = 500;
		int newHeight = (int)(((float)newWidth / (float)width) * (float)height);

		float scaleWidth = ((float)newWidth)/width;
		float scaleHeight = ((float)newHeight)/height;

		Log.d(TAG, "rescaleBitmap() " +  scaleWidth + "," + scaleHeight);

		Matrix matrix = new Matrix();
		matrix.postScale(scaleWidth, scaleHeight);
		
		Bitmap scaled = Bitmap.createBitmap(orig, 0, 0, width, height, matrix, true);
		orig.recycle();
		return scaled;
	}
	
	protected Handler mHandler = new Handler() {
		String result = null;
		@Override
		public void handleMessage(Message msg) {
			result = (String) msg.obj;
			try {
				dismissDialog(1);
				if (result != null) {
					if (result.contains((CharSequence) "stat=\"fail\"")) {
						if (result.contains((CharSequence) "code=\"1001\"")) {
							Toast.makeText(SendTweet.this, R.string.dialog_send_incorrect_password, Toast.LENGTH_LONG).show();
							startActivity(new Intent(SendTweet.this, PreferencesActivity.class));
						} else if (result.contains((CharSequence) "Duplicate Image")) {
							Toast.makeText(SendTweet.this, R.string.dialog_send_duplicate, Toast.LENGTH_LONG).show();
						} else {
							String appmsg = new String("");
							int posstart = result.indexOf("msg=") + 5;
							if (posstart >= 0) {
								int posend = result.indexOf("\" />", posstart);
								if (posend >= 0) {
									appmsg = result.substring(posstart, posend);
								}
							}
							Toast.makeText(SendTweet.this, R.string.dialog_send_error + appmsg, Toast.LENGTH_LONG).show();
						}
					} else {
						Toast.makeText(SendTweet.this, R.string.dialog_send_success, Toast.LENGTH_LONG).show();
						finish();
					}
				} else {
					Toast.makeText(SendTweet.this, R.string.dialog_send_fail, Toast.LENGTH_LONG).show();
				}
			} catch (Exception e) {
				Log.d(TAG, "mHandler Exception" + e.toString());
			}
			
		}
	};
	
	protected Runnable mSendUpdate = new Runnable() {
		public void run() {
			String result = null;
	        getAllPreferences();
	        String usedGateway = mUseSecureGateway ? mSecurePicGateway : mPicGateway;
			String msg = txtCompose.getText().toString();
			Log.d(TAG, "mSendUpdate run(" + usedGateway + ")");
			try {
				HttpClient client = new DefaultHttpClient(new BasicHttpParams());
				HttpPost method = new HttpPost(usedGateway);
				method.setHeader("User-Agent", USER_AGENT);
				client.getParams().setIntParameter(HttpConnectionParams.CONNECTION_TIMEOUT, DEFAULT_POST_REQUEST_TIMEOUT);
				client.getParams().setIntParameter(HttpConnectionParams.SO_TIMEOUT, DEFAULT_POST_REQUEST_TIMEOUT);
				
				InputStream is = getContentResolver().openInputStream(mUri);
				InputStreamEntity ise = new InputStreamEntity(is, -1L); 
				byte[] data = EntityUtils.toByteArray(ise);

				MultipartEntity entity = new MultipartEntity();
				entity.addPart("media", new ByteArrayBody(data, IMAGE_MIME, IMAGE_FILENAME));
				entity.addPart("username", new StringBody(mUsername, Charset.forName("UTF-8")));
				entity.addPart("password", new StringBody(mPassword, Charset.forName("UTF-8")));
				entity.addPart("message", new StringBody(msg, Charset.forName("UTF-8")));
				method.setEntity(entity);
				Log.d(TAG, "mSendUpdate run() length = " + entity.getContentLength());
				HttpResponse response = client.execute(method);
				result = retrieveInputStream(response.getEntity());
				Log.d(TAG, "mSendUpdate run() result / " + result.toString());
			} catch (IOException e) {
				Log.d(TAG, "mSendUpdate run() IOException / " + e.toString());
			} catch (Exception e) {
				Log.d(TAG, "mSendUpdate run() Exception / " + e.toString());
			}
			mHandler.sendMessage(mHandler.obtainMessage(1, result));
		}
	};

	/**
	 * Retrieve the input stream from the HTTP connection.
	 * 
	 * @param httpEntity
	 * @return String
	 */
	protected String retrieveInputStream(HttpEntity httpEntity) {
		int length = (int) httpEntity.getContentLength();
		if (length > 0) {
			StringBuffer stringBuffer = new StringBuffer(length);
			try {
				InputStreamReader inputStreamReader = new InputStreamReader(httpEntity.getContent(), HTTP.UTF_8);
				char buffer[] = new char[length];
				int count;
				while ((count = inputStreamReader.read(buffer, 0, length - 1)) > 0) {
					stringBuffer.append(buffer, 0, count);
				}
			} catch (UnsupportedEncodingException e) {
				Log.e(TAG, e.getMessage());
			} catch (IllegalStateException e) {
				Log.e(TAG, e.getMessage());
			} catch (IOException e) {
				Log.e(TAG, e.getMessage());
			}
			return stringBuffer.toString();
		} else {
			String res = null;
			try {
				res = convertStreamToString(httpEntity.getContent());
			} catch (IOException e) {
				Log.e(TAG, e.getMessage());
			}
			return res;
		}
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {
		mProgressDialog = new ProgressDialog(this);
		mProgressDialog.setIcon(android.R.drawable.ic_dialog_info);
		mProgressDialog.setTitle(R.string.dialog_title_sending_message);
		mProgressDialog.setMessage(getText(R.string.dialog_summary_sending_message));
		return mProgressDialog;
	}
	
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0, MENU_PREFERENCES, 0, R.string.menu_preferences).setIcon(R.drawable.ic_menu_preferences);
		menu.add(0, MENU_CANCEL, 0, R.string.menu_cancel).setIcon(android.R.drawable.ic_menu_close_clear_cancel);
		return true;
	}
	
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case MENU_PREFERENCES:
			startActivity(new Intent(SendTweet.this, PreferencesActivity.class));
			return true;
		case MENU_CANCEL:
			finish();
			return true;
		}
		return false;
	}

	private static String convertStreamToString(InputStream is) {
		/*
		 * To convert the InputStream to String we use the
		 * BufferedReader.readLine() method. We iterate until the BufferedReader
		 * return null which means there's no more data to read. Each line will
		 * appended to a StringBuilder and returned as String.
		 */
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		StringBuilder sb = new StringBuilder();

		String line = null;
		try {
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return sb.toString();
	}
	
	private void getAllPreferences() {
        mUsername = mSP.getString(PreferencesActivity.KEY_TWITTER_USERNAME, null);
        mPassword = mSP.getString(PreferencesActivity.KEY_TWITTER_PASSWORD, null);
        mPicGateway = mSP.getString(PreferencesActivity.KEY_PICTURE_GATEWAY, null);
        mUseSecureGateway = mSP.getBoolean(PreferencesActivity.KEY_USE_SECURE_GATEWAY, false);
        mSecurePicGateway = mSP.getString(PreferencesActivity.KEY_SECURE_PICTURE_GATEWAY, null);
	}
}